DynamicQuant
将 FP32 输入张量按给定的 scale 和 zero point(zp)动态量化为 INT8 输出张量。 支持按整张量量化或按指定轴分段量化(per-axis dynamic quantization)。
其中:
\(x_i\) 为输入浮点值
\(scale\) 为量化比例因子
\(zp\) 为零点(zero point)
\(q_{min} = -128\)
\(q_{max} = 127\)
当输入为 \(+\infty\) 或 \(-\infty\) 时,输出分别饱和到最大或最小量化值。
—
- 输入:
real_values - 输入 FP32 数据地址
element_num - 输入元素总数
scale - 量化 scale 数组地址
zp - 量化 zero point 数组地址
segment_num - 分段数量(用于按轴量化)
- axis_num - 量化轴标识
0:整张量量化(per-tensor)!=0:按轴分段量化(per-axis)
- 输出:
quant_values - 输出 INT8 量化结果地址
—
- 支持平台:
FT78NEMT7004
—
备注
当前算子仅支持 FP32Fp16 → INT8 的动态量化
当
axis_num = 0时,仅使用scale[0]与zp[0]进行整张量量化当
axis_num != 0时,输入按segment_num进行分段,每段使用对应的scale[i]与zp[i]分段大小通过
UP_DIV(element_num, segment_num)计算,最后一段自动处理剩余元素量化结果会被限制在
[-128, 127]范围内
—
私有存储版本:
-
void fp_QuantData_p(float *real_values, int8_t *quant_values, int element_num, float *scale, int *zp, int segment_num, int axis_num)
-
void hp_QuantData_p(half *real_values, half *quant_values, int element_num, half *scale, int *zp, int segment_num, int axis_num)
—
C调用示例:
1#include <stdio.h> 2#include <quant.h> 3 4int main(int argc, char* argv[]) { 5 float *input = (float *)0x10000000; // FP32 输入 6 int8_t *output = (int8_t *)0x10004000; // INT8 输出 7 float scale[4] = {0.1f, 0.12f, 0.11f, 0.09f}; 8 int zp[4] = {0, 0, 0, 0}; 9 int element_num = 1024; 10 int segment_num = 4; 11 int axis_num = 1; 12 13 fp_QuantData_p(input, output, element_num, 14 scale, zp, segment_num, axis_num); 15 16 return 0; 17}
—
共享存储版本:
-
void fp_QuantData_s(float *real_values, int8_t *quant_values, int element_num, float *scale, int *zp, int segment_num, int axis_num, int core_mask)
-
void hp_QuantData_s(half *real_values, half *quant_values, int element_num, half *scale, int *zp, int segment_num, int axis_num, int core_mask)
—
C调用示例:
1#include <stdio.h> 2#include <quant.h> 3 4int main(int argc, char* argv[]) { 5 float *input = (float *)0x10000000; // FP32 输入 6 int8_t *output = (int8_t *)0x10004000; // INT8 输出 7 float scale[4] = {0.1f, 0.12f, 0.11f, 0.09f}; 8 int zp[4] = {0, 0, 0, 0}; 9 int element_num = 1024; 10 int segment_num = 4; 11 int axis_num = 1, core_mask = 0xff; 12 13 fp_QuantData_s(input, output, element_num, 14 scale, zp, segment_num, axis_num, core_mask); 15 16 return 0; 17}
—
实现说明:
当
axis_num == 0时:对整个输入数组执行一次统一量化
等价于 per-tensor quantization
当
axis_num != 0时:输入数据按
segment_num均分为多个分段每个分段使用独立的
scale[i]与zp[i]等价于 per-axis dynamic quantization
核心量化过程由
DoQuantizeFp32ToInt8完成,包括:反 scale 计算
四舍五入
饱和裁剪
INF 特殊值处理